package com.five.matebook.activity.matebook;

import android.content.Context;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.five.matebook.activity.columeedit.CustomColume;
import com.five.matebook.activity.db.DbHelper;
import com.five.matebook.activity.income.IncomeColume;
import com.five.matebook.activity.outcome.OutcomeColume;
import com.five.matebook.utils.DeviceUtils;
import com.five.matebook.utils.FileUtils;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class MateBookManager {
    private static final String TAG = MateBookManager.class.getSimpleName();

    private static final String DEFAULT_MATEBOOK_ID = DeviceUtils.getDeviceUuid();

    private List<Matebook> matebookList = new LinkedList<>();
    public MateBookManager() {
    }

    public void setMatebookList(List<Matebook> matebookList) {
        this.matebookList = matebookList;
    }

    public void clear() {
        this.matebookList.clear();
    }

    public List<Matebook> getMatebookList() {
        return matebookList;
    }

    public interface ITransver {
        void doTrasver(Matebook m);
    }
    public synchronized void trasverLocked(ITransver transver) {
        for (Matebook m :matebookList) {
            transver.doTrasver(m);
        }
    }

    public List<String> getMatebookNameList() {
        List<String> ret = new ArrayList<>();
        synchronized (this) {
            for (Matebook matebook :matebookList) {
                ret.add(matebook.getAlias());
            }
        }
        return ret;
    }

    private int nowMatebookIndex = -1;
    public synchronized boolean loadNowChoosedMatebook(Context context) {
        if (nowMatebookIndex >= 0 && nowMatebookIndex < matebookList.size() ) {
            return chooseMatebook(context, matebookList.get(nowMatebookIndex));
        }
        return false;
    }

    public synchronized boolean chooseMatebook(Context context, int index) {
        if (index >= 0 && index < matebookList.size()) {
            return chooseMatebook(context, matebookList.get(index));
        }
        return false;
    }

    public boolean chooseMatebook(Context context, String matebookId) {

        for (Matebook m : matebookList) {
            if (m.getId().equals(matebookId)) {
                return chooseMatebook(context, m);
            }
        }
        return false;
    }

    public synchronized boolean chooseMatebook(Context context, Matebook matebook) {
        if (matebook == null) {
            return false;
        }

        int index = -1;
        for (int i=0; i<matebookList.size(); i++) {
            Matebook m = matebookList.get(i);
            if (matebook.equals(m)) {
                index = i;
                break;
            }
        }
        if (index < 0) {
            Log.e(TAG, "chooseMatebook failed()");
            return false;
        }

        // new matebook is valid
        // try close old db helper
        {
            if (this.nowMatebookIndex >= 0 && this.nowMatebookIndex < matebookList.size()) {
                DbHelper.doClose();
            }
        }

        this.nowMatebookIndex = index;

        DbHelper.setsDbName(context, matebook.getFileName());
        {
            // 初始化表
            CustomColume.init(context);
            OutcomeColume.init(context);
            IncomeColume.init(context);
        }
        return true;
    }

    public synchronized Matebook addMatebook(String id, String alias) {
        if (TextUtils.isEmpty(id) || TextUtils.isEmpty(alias)) {
            return null;
        }
        for (Matebook matebook : matebookList) {
            if (id.equals(matebook.getId()) && alias.equals(matebook.getAlias())) {
                return null;
            }
        }
        Matebook ret = new Matebook(id, alias);
        matebookList.add(ret);
        return ret;
    }

    public synchronized Matebook generateDefaultMatebook() {
        Matebook m = getDefaultMatebook();
        return addMatebook(m.getId(), m.getAlias());
    }

    public Matebook getDefaultMatebook() {
        return new Matebook(DEFAULT_MATEBOOK_ID, "matebook");
    }

    public Matebook get(int index) {
        synchronized (this) {
            if (index >= 0 && index < matebookList.size()) {
                return matebookList.get(index);
            }
        }
        return null;
    }

    public synchronized Matebook getNowChoosed() {
        return get(nowMatebookIndex);
    }

    public synchronized int getNowChoosedIndex() {
        return nowMatebookIndex;
    }

    public boolean hasMatebook() {
        return this.matebookList.size() != 0;
    }

    public synchronized void setHasUpdate(boolean hasUpdate) {
        for (Matebook m : matebookList) {
            if (!m.isMine())    continue;
            m.setHasUpdate(hasUpdate);
        }
    }

    public synchronized boolean hasUpdate() {
        return  getUpdateCount() > 0;
    }

    public synchronized int getUpdateCount() {
        int ret = 0;
        for (Matebook m : matebookList) {
            if (!m.isMine())    continue;
            ret += m.getUpdateCount();
        }
        return ret;
    }

    public synchronized boolean backup(Context context) {
        File dir = new File(Environment.getExternalStorageDirectory(), "matebook");
        Log.d(TAG, "backup to dir:" + dir.getPath());
        if (!dir.exists()) {
            dir.mkdir();
        }
        for (Matebook m : matebookList) {
            File dbFile = m.getDbFile(context);
            File backFile = new File(dir, dbFile.getName());
            if (backFile.exists()) {
                backFile.delete();
            }
            if (!FileUtils.copyFile(dbFile, backFile)) {
                return false;
            }
        }
        return true;
    }
}
